﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace Scrat.Core.Common
{
    /*
     * 用于传输文件相关的TCP工具类
     * 使用 Serialize进行序列化 Deserialize进行反序列化, 对应得实体类应添加 [Serialize]
     * 注意 BinaryFormatter 存在安全问题,尽量不使用
     * https://learn.microsoft.com/zh-cn/dotnet/standard/serialization/binaryformatter-security-guide
     */
    public static class GeneralTool
    {

        /// <summary>
        /// 合并两个byte数组
        /// </summary>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <returns>
        ///  return = arg1 + arg2
        /// </returns>
        public static byte[] MergeBytes(byte[] arg1, byte[] arg2)
        {
            byte[] container = new byte[arg1.Length + arg2.Length];
            arg1.CopyTo(container, 0);
            arg2.CopyTo(container, arg1.Length);
            return container;
        }

        /// <summary>
        /// 拆分数组
        /// </summary>
        /// <param name="data">要操作的byte数组</param>
        /// <param name="oringinStartIndex">第一个数组开始拆分的位置</param>
        /// <param name="destPreByteLength">第一个数组的长度</param>
        /// <returns>
        ///     [preByte, sufByte]
        /// </returns>
        public static List<byte[]> SplitByte(byte[] dataArr, int PreByteLength)
        {
            List<byte[]> container = new List<byte[]>();
            byte[] preByte = dataArr.Take(PreByteLength).ToArray();
            byte[] sufByte = dataArr.Skip(PreByteLength).ToArray();
            container.Add(preByte);
            container.Add(sufByte);
            return container;
        }

        public static byte[] Serialize<T>(T t)
        {
            byte[] arr = null;
            if (t != null)
            {
                using (MemoryStream mStream = new MemoryStream())
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    formatter.Serialize(mStream, t);
                    mStream.Flush();
                    arr = mStream.ToArray();
                }
            }
            return arr;
        }
        public static T Deserialize<T>(byte[] arr)
        {
            T t = default;
            using (MemoryStream mStream = new MemoryStream())
            {
                mStream.Write(arr, 0, arr.Length);
                mStream.Flush();
                mStream.Seek(0, SeekOrigin.Begin);
                BinaryFormatter formatter = new BinaryFormatter();
                t = (T)formatter.Deserialize(mStream);
            }
            return t;
        }
    }
}
